'use strict';

const util = {
  /**
	 * 校验指定值是否是对象
	 * @param {*} val
	 */
  isObject(val) {
    return Object.prototype.toString.call(val) === '[object Object]';
  },
  /**
	 * 校验指定值是否是函数，如果是函数则立即执行
	 * @param (object|function, function|[params], [...params])
	 */
  isFunctionCall() {
    const arg = Array.from(arguments);
    let t = this;
    let fn = arg[0];
    let params = arg.slice(1);
    if (util.isObject(arg[0])) {
      t = arg[0];
      fn = arg[1];
      params = arg.slice(2);
    }
    if (util.isFunction(fn)) {
      return fn.apply(t, params);
    }
    return false;

  },
  /**
	 * 校验指定值是否是函数
	 * @param {*} fun
	 */
  isFunction(fun) {
    return typeof fun === 'function';
  },
  /**
	 * 对象深拷贝
	 * @param {object} target 目标对象 （JSON.parse(JSON.stringify(object))弃用原因：Infinity等类似的值会被处理成 null）
	 */
  deepClone(target) {
    let result;
    if (typeof target === 'object') {
      if (Array.isArray(target)) {
        result = [];
        for (const i in target) {
          result.push(util.deepClone(target[i]));
        }
      } else if (target === null) {
        result = null;
      } else if (target.constructor === RegExp) {
        result = target;
      } else {
        result = {};
        for (const i in target) {
          result[i] = util.deepClone(target[i]);
        }
      }
    } else {
      result = target;
    }
    return result;
  },
  /**
	 * 对象深覆盖（不会合并对象，基于被覆盖对象的属性遍历赋值需覆盖的对象属性）
	 * @param {object} target 被覆盖的目标对象
	 * @param {object} source 需覆盖的对象
	 */
  deepAssign(target, source) {
    if (util.isObject(target) && util.isObject(source) && (target !== source)) {
      for (const key in target) {
        if (target.hasOwnProperty(key)) {
          if (source[key] !== undefined) {
            if (util.isObject(target[key]) && util.isObject(source[key])) {
              target[key] = util.deepAssign(target[key], source[key]);
            } else {
              target[key] = source[key];
            }
          }
        }
      }
    }
    return target;
  },
  /**
	 * 对象深合并
	 * @arguments (...object)
	 */
  deepMerge() {
    const target = {};
    const arg = Array.from(arguments);
    const merge = obj => {
      for (const key in obj) {
        if (obj.hasOwnProperty(key)) {
          if (util.isObject(obj[key])) {
            target[key] = util.deepMerge(target[key], obj[key]);
          } else {
            target[key] = obj[key];
          }
        }
      }
    };
    for (let i = 0; i < arg.length; i++) {
      if (util.isObject(arg[i])) {
        merge(arg[i]);
      }
    }
    return target;
  },
  /**
	 * 生成uuid
	 */
  uuid() {
    let uuid = '';
    for (let i = 1; i <= 28; i++) {
      const n = Math.floor(Math.random() * 16.0).toString(16);
      uuid += n;
      // eslint-disable-next-line eqeqeq
      if (i == 8 || i == 12 || i == 16 || i == 20) uuid += '';
    }
    return uuid;
  },
};

module.exports = util;

